package org.netty.demo.lihh.notice.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.Getter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;

@Component("nettyServer")
public class NettyServer {
  private static final Logger log = LoggerFactory.getLogger(NettyServer.class);
  private final EventLoopGroup bossGroup = new NioEventLoopGroup(1);
  private final EventLoopGroup workerGroup = new NioEventLoopGroup(1);
  
  @Getter
  private Channel channel;
  
  public ChannelFuture bind(InetSocketAddress address) {
    ChannelFuture channelFuture = null;
    
    try {
      ServerBootstrap b = new ServerBootstrap();
      b.group(bossGroup, workerGroup)
          .channel(NioServerSocketChannel.class)
          .option(ChannelOption.SO_BACKLOG, 128)
          .childHandler(new MyChannelInitializer());
      
      // 除了绑定端口外 && 同时实现了优雅降级
      channelFuture = b.bind(address).syncUninterruptibly();
      channel = channelFuture.channel();
    } finally {
      // 是否启动成功
      if (null != channelFuture && channelFuture.isSuccess())
        log.info("Server started on {}", address.getPort());
      else
        log.error("Server failed to start on {}", address.getPort());
    }
    return channelFuture;
  }
  
  public void destroy() {
    if (null == channel) return;
    channel.close();
    bossGroup.shutdownGracefully();
    workerGroup.shutdownGracefully();
  }
}
